﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using SkypeTranslator.Utilities.Attributes;

namespace SkypeTranslator.Utilities
{
	public class ItemEventArgs<TItem> : EventArgs
	{
		private TItem _item;
		public TItem Item
		{
			get
			{
				return this._item;
			}
		}
		public ItemEventArgs(TItem item)
		{
			this._item = item;
		}
	}

	public class EventsHelper
	{
		public static void Fire(Delegate del, object sender, EventArgs e)
		{
			if (del == null)
			{
				return;
			}
			Delegate[] invocationList = del.GetInvocationList();
			Delegate[] array = invocationList;
			for (int i = 0; i < array.Length; i++)
			{
				Delegate @delegate = array[i];
				try
				{
					@delegate.DynamicInvoke(new object[]
					{
						sender, 
						e
					});
				}
				catch (Exception)
				{
					//Platform.Log(LogLevel.Error, message);
					throw;
				}
			}
		}
	}

	namespace Threading
	{
		//public abstract class ThreadPoolBase
		//{
		//    public enum StartStopState
		//    {
		//        Starting,
		//        Started,
		//        Stopping,
		//        Stopped
		//    }

		//    public static readonly int MinConcurrency = 1;
		//    public static readonly int MaxConcurrency = 100;
		//    private readonly object _startStopSyncLock = new object();
		//    private ThreadPoolBase.StartStopState _state;
		//    private bool _completeBeforeStop;
		//    private readonly List<Thread> _threads;
		//    private int _concurrency = ThreadPoolBase.MinConcurrency;
		//    private ThreadPriority _threadPriority;
		//    private string _threadPoolName = "Pool";
		//    private event EventHandler<ItemEventArgs<ThreadPoolBase.StartStopState>> _startStopEvent
		//    {
		//        [MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
		//        add
		//        {
		//            this._startStopEvent = (EventHandler<ItemEventArgs<ThreadPoolBase.StartStopState>>)Delegate.Combine(this._startStopEvent, value);
		//        }
		//        [MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
		//        remove
		//        {
		//            this._startStopEvent = (EventHandler<ItemEventArgs<ThreadPoolBase.StartStopState>>)Delegate.Remove(this._startStopEvent, value);
		//        }
		//    }
		//    public event EventHandler<ItemEventArgs<ThreadPoolBase.StartStopState>> StartStopStateChangedEvent
		//    {
		//        add
		//        {
		//            object startStopSyncLock;
		//            Monitor.Enter(startStopSyncLock = this._startStopSyncLock);
		//            try
		//            {
		//                this._startStopEvent = (EventHandler<ItemEventArgs<ThreadPoolBase.StartStopState>>)Delegate.Combine(this._startStopEvent, value);
		//            }
		//            finally
		//            {
		//                Monitor.Exit(startStopSyncLock);
		//            }
		//        }
		//        remove
		//        {
		//            object startStopSyncLock;
		//            Monitor.Enter(startStopSyncLock = this._startStopSyncLock);
		//            try
		//            {
		//                this._startStopEvent = (EventHandler<ItemEventArgs<ThreadPoolBase.StartStopState>>)Delegate.Remove(this._startStopEvent, value);
		//            }
		//            finally
		//            {
		//                Monitor.Exit(startStopSyncLock);
		//            }
		//        }
		//    }
		//    public bool Active
		//    {
		//        get
		//        {
		//            object startStopSyncLock;
		//            Monitor.Enter(startStopSyncLock = this._startStopSyncLock);
		//            bool result;
		//            try
		//            {
		//                result = (this._state != ThreadPoolBase.StartStopState.Stopped);
		//            }
		//            finally
		//            {
		//                Monitor.Exit(startStopSyncLock);
		//            }
		//            return result;
		//        }
		//    }
		//    public int Concurrency
		//    {
		//        get
		//        {
		//            return this._concurrency;
		//        }
		//        set
		//        {
		//            if (this.Active)
		//            {
		//                throw new InvalidOperationException(string.Format(SR.ExceptionThreadPoolMustBeStopped, "Concurrency"));
		//            }
		//            Platform.CheckPositive(value, "Concurrency");
		//            Platform.CheckArgumentRange(value, ThreadPoolBase.MinConcurrency, ThreadPoolBase.MaxConcurrency, "Concurrency");
		//            this._concurrency = value;
		//        }
		//    }
		//    public string ThreadPoolName
		//    {
		//        get
		//        {
		//            return this._threadPoolName;
		//        }
		//        set
		//        {
		//            this._threadPoolName = value;
		//        }
		//    }
		//    public ThreadPriority ThreadPriority
		//    {
		//        get
		//        {
		//            return this._threadPriority;
		//        }
		//        set
		//        {
		//            if (this.Active)
		//            {
		//                throw new InvalidOperationException(string.Format(SR.ExceptionThreadPoolMustBeStopped, "ThreadPriority"));
		//            }
		//            this._threadPriority = value;
		//        }
		//    }
		//    protected bool CompleteBeforeStop
		//    {
		//        get
		//        {
		//            object startStopSyncLock;
		//            Monitor.Enter(startStopSyncLock = this._startStopSyncLock);
		//            bool completeBeforeStop;
		//            try
		//            {
		//                completeBeforeStop = this._completeBeforeStop;
		//            }
		//            finally
		//            {
		//                Monitor.Exit(startStopSyncLock);
		//            }
		//            return completeBeforeStop;
		//        }
		//    }
		//    protected ThreadPoolBase.StartStopState State
		//    {
		//        get
		//        {
		//            object startStopSyncLock;
		//            Monitor.Enter(startStopSyncLock = this._startStopSyncLock);
		//            ThreadPoolBase.StartStopState state;
		//            try
		//            {
		//                state = this._state;
		//            }
		//            finally
		//            {
		//                Monitor.Exit(startStopSyncLock);
		//            }
		//            return state;
		//        }
		//    }
		//    protected ThreadPoolBase(int concurrency)
		//        : this()
		//    {
		//        this.Concurrency = concurrency;
		//    }
		//    protected ThreadPoolBase()
		//    {
		//        this._state = ThreadPoolBase.StartStopState.Stopped;
		//        this._completeBeforeStop = false;
		//        this._threads = new List<Thread>();
		//        this._threadPriority = ThreadPriority.Normal;
		//    }
		//    protected virtual bool OnStart()
		//    {
		//        object startStopSyncLock;
		//        Monitor.Enter(startStopSyncLock = this._startStopSyncLock);
		//        bool result;
		//        try
		//        {
		//            if (this._state != ThreadPoolBase.StartStopState.Stopped)
		//            {
		//                result = false;
		//                return result;
		//            }
		//            this._state = ThreadPoolBase.StartStopState.Starting;
		//            EventsHelper.Fire(this._startStopEvent, this, new ItemEventArgs<ThreadPoolBase.StartStopState>(this._state));
		//        }
		//        finally
		//        {
		//            Monitor.Exit(startStopSyncLock);
		//        }
		//        return true;
		//        return result;
		//    }
		//    protected virtual void OnStarted()
		//    {
		//        object startStopSyncLock;
		//        Monitor.Enter(startStopSyncLock = this._startStopSyncLock);
		//        try
		//        {
		//            this._state = ThreadPoolBase.StartStopState.Started;
		//            EventsHelper.Fire(this._startStopEvent, this, new ItemEventArgs<ThreadPoolBase.StartStopState>(this._state));
		//        }
		//        finally
		//        {
		//            Monitor.Exit(startStopSyncLock);
		//        }
		//    }
		//    protected virtual bool OnStop(bool completeBeforeStop)
		//    {
		//        object startStopSyncLock;
		//        Monitor.Enter(startStopSyncLock = this._startStopSyncLock);
		//        bool result;
		//        try
		//        {
		//            if (this._state != ThreadPoolBase.StartStopState.Started)
		//            {
		//                result = false;
		//                return result;
		//            }
		//            this._completeBeforeStop = completeBeforeStop;
		//            this._state = ThreadPoolBase.StartStopState.Stopping;
		//            EventsHelper.Fire(this._startStopEvent, this, new ItemEventArgs<ThreadPoolBase.StartStopState>(this._state));
		//        }
		//        finally
		//        {
		//            Monitor.Exit(startStopSyncLock);
		//        }
		//        return true;
		//        return result;
		//    }
		//    protected virtual void OnStopped()
		//    {
		//        object startStopSyncLock;
		//        Monitor.Enter(startStopSyncLock = this._startStopSyncLock);
		//        try
		//        {
		//            this._state = ThreadPoolBase.StartStopState.Stopped;
		//            EventsHelper.Fire(this._startStopEvent, this, new ItemEventArgs<ThreadPoolBase.StartStopState>(this._state));
		//        }
		//        finally
		//        {
		//            Monitor.Exit(startStopSyncLock);
		//        }
		//    }
		//    public void Start()
		//    {
		//        if (!this.OnStart())
		//        {
		//            return;
		//        }
		//        for (int i = 0; i < this._concurrency; i++)
		//        {
		//            ThreadStart start = new ThreadStart(this.RunThread);
		//            Thread thread = new Thread(start);
		//            thread.Name = string.Format("{0}:{1}", this._threadPoolName, thread.ManagedThreadId);
		//            thread.IsBackground = true;
		//            thread.Priority = this._threadPriority;
		//            thread.Start();
		//            this._threads.Add(thread);
		//        }
		//        this.OnStarted();
		//    }
		//    public void Stop()
		//    {
		//        this.Stop(false);
		//    }
		//    public void Stop(bool completeBeforeStop)
		//    {
		//        if (!this.OnStop(completeBeforeStop))
		//        {
		//            return;
		//        }
		//        foreach (Thread current in this._threads)
		//        {
		//            current.Join();
		//        }
		//        this._threads.Clear();
		//        this.OnStopped();
		//    }
		//    protected abstract void RunThread();
		//}
	}
}
